//include core.js before this file
gOneClickExtension.altPressedDown = false; //Last click in thread tree was with pressed "alt" key. Uses to prevent menu selection after click.
gOneClickExtension.Preferences = null;     //All add-on preferences. See core.js.
gOneClickExtension.appVersion = null;      //Thunderbird version. Used to check possibility to use "Show InOut" add-on.
gOneClickExtension.IsCleanSubjectInstalled = false;      //Thunderbird version. Used to check possibility to use "Show InOut" add-on.

//Preference observer. Refills "gOneClickExtension.Preferences" after any changes in branch from "gOneClickExtension.prefPrefixString"
gOneClickExtension.prefObserver =
{
    register: function()
    {
		var prefService = Components.classes["@mozilla.org/preferences-service;1"]
                                .getService(Components.interfaces.nsIPrefService);
    
		this._branch = prefService.getBranch(gOneClickExtension.prefPrefixString);

		this._branch.QueryInterface(Components.interfaces.nsIPrefBranch2);

		this._branch.addObserver("", this, false);
	},

	unregister: function()
	{
		if( !this._branch ) return;
		this._branch.removeObserver("", this);
	},

	observe: function(aSubject, aTopic, aData)
	{
		if( aTopic != "nsPref:changed" ) return;
		gOneClickExtension.Preferences = gOneClickExtension.LoadPreferences();
	}
}

//Clean quick search window. Works for both 2.0 and 3.0 versions.
gOneClickExtension.ClearSearch = function()
{
	if ( window.onClearSearch )
	{ // v2
		onClearSearch(); 
	}
	else
	{ // v3
		var searchBar = document.getElementById("searchInput");
		searchBar.value = '';
		searchBar.doSearch(); 
		searchBar.select();
	}
}


//only "subject", "sender", "recipient" and "correspondent" (Show InOut add-on) columns are supported
//Works for both 2.0 and 3.0 Thunderbird versions.
gOneClickExtension.GetSearchMode = function( in_id )
{
	if ( window.QuickSearchConstants )
	{ //v3
		if ( in_id == "subjectCol" )
			return QuickSearchConstants.kQuickSearchSubject;
		else if ( in_id == "senderCol" )
			return QuickSearchConstants.kQuickSearchFrom;
		else if ( in_id == "recipientCol" )
			return QuickSearchConstants.kQuickSearchRecipient;
		else if ( in_id == "sio_inoutaddressCol" && gOneClickExtension.appVersion != "3.0b4" ) // ShowInOut extension support (doesn't work with )
            return 99;
		else
			return -1;
	}
	else // v2
	{
		if ( in_id == "subjectCol" )
			return 0;
		else if ( in_id == "senderCol" )
			return 1;
		else if ( in_id == "recipientCol" )
			return 5;
		else if ( in_id == "sio_inoutaddressCol" ) // ShowInOut extension support
            return 99;
		else 
			return -1;
	}
}

//Check conditions for search: corresponding modifier is hold on or middle button is pressed
gOneClickExtension.CheckSearchActive = function( event )
{
    //middle button is enabled and pressed
    if ( gOneClickExtension.Preferences.enableMiddleButton && event.button == 1 ) return true;

    //check modifiers
	var selectionType = gOneClickExtension.Preferences.selectionType;
	if ( selectionType == "alt" )
		return event.altKey;
	else if ( selectionType == "shift" )
		return event.shiftKey;
    else if ( selectionType == "ctrl" )
		return event.ctrlKey;
}

//Replace string using user-defined regexp. If not match, return original strings. 
//If multiple matches, return all replaces, concatinated with OR operator
gOneClickExtension.RegexpReplaceString = function( str )
{
    if ( !gOneClickExtension.Preferences.enableRegexp ) return str;
    //dump("OneClickSearch: RegexpReplaceString(), beginning: " + gOneClickExtension.Preferences.regexpReplace + "\n");

	var regexp = new RegExp(gOneClickExtension.Preferences.regexpMatch, "gi");
    var r_match = str.match(regexp);

    if ( !r_match ) return str;

    var out_str = "";

    //dump("OneClickSearch: RegexpReplaceString(), before replace: " + gOneClickExtension.Preferences.regexpReplace + "\n");
    for (i = 0; i < r_match.length; i++ )
    {
        if (i) out_str += "|";
        out_str += r_match[i].replace(regexp, gOneClickExtension.Preferences.regexpReplace);
    }

    return out_str;
}

//Simply removes fixed types of prefexes. I'm going to further work around this feature...
gOneClickExtension.removePrefixes = function( str )
{
    var prefixes = new Array(
        /^re:\s*(.*)$/i, 
        /^re\[\d+\]:?\s*(.*)$/i, 
        /^fw:\s*(.*)$/i,
        /^fwd:\s*(.*)$/i,
        /^\[fwd:\s*(.*)\]\s*$/i,
        /^\s+(.*)$/
    );

    var flag;
    do 
    {
        flag = 0;
        for (i in prefixes)
        {
            if (str.search(prefixes[i]) != -1)
            {
                str = str.replace(prefixes[i], '$1'); 
                flag = 1;
            }
        }
    } while(flag);

    return str;
}

//Clicked at message thread event
gOneClickExtension.onClicked = function ( event )
{
	if ( !gOneClickExtension.CheckSearchActive( event ) ) return;

    //to prevent menu activation after click
	if ( event.altKey ) gOneClickExtension.altPressedDown = true;

	var row = {};
	var col = {};
	var childElt = {};
	event.currentTarget.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col, childElt);

    var searchMode = gOneClickExtension.GetSearchMode( col.value.id );
	if ( searchMode < 0 ) return;

	var sCellText = event.currentTarget.view.getCellText(row.value, col.value);

    if ( col.value.id == "subjectCol" )
    {
        if ( gOneClickExtension.IsCleanSubjectInstalled ) 
        {
            sCellText = sbiz.CleanSubject.RemovePrefixes( sCellText, sbiz.CleanSubject.prefixes );
            dump(sCellText + "\n");
            dump(sbiz.CleanSubject.prefixes + "\n");
        }
        else
        {
            //some predefined set of prefixes
            sCellText = gOneClickExtension.removePrefixes( sCellText );
        }
        sCellText = gOneClickExtension.RegexpReplaceString( sCellText );
    }
	
	document.getElementById("searchInput").value = sCellText;
	document.getElementById("searchInput").clearButtonHidden = false;

	document.getElementById("searchInput").showingSearchCriteria = false;	

	document.getElementById("searchInput").searchMode = searchMode;

	if ( document.getElementById("searchInput").doSearch )
	{
		document.getElementById("searchInput").doSearch(); //v3
	}
	else
	{
        selectedHdr = gDBView.hdrForFirstSelectedMessage;
		onEnterInSearchBar(); //v2
        //gDBView.selectMessage(selectedMessage);
        gDBView.selectMsgByKey(selectedHdr.messageKey);
        var treeView = gDBView.QueryInterface(Components.interfaces.nsITreeView);
        EnsureRowInThreadTreeIsVisible(treeView.selection.currentIndex);
	}

	event.preventDefault();
	event.stopPropagation();
}

//Pressed some key when focus is at quick search panel
gOneClickExtension.onSearchKeyPress = function (event)
{
	// 27 == esc
	if ( event && event.keyCode == 27 && document.getElementById("searchInput").value != "" )
		gOneClickExtension.ClearSearch();
}

//1) Prevent main menu activation after "alt" key press
//2) Clear search if "esc" is pressed
gOneClickExtension.onWindowKeyUp = function (event)
{
	//we hold on "alt" and clicked at message -> we are going to search messages, prevent menu selection
	if ( gOneClickExtension.altPressedDown && event.altKey == false && event.keyCode == 18 )
	{
		gOneClickExtension.altPressedDown = false;
		event.stopPropagation();
		return;
	}

    // 27 == esc
	if ( event.keyCode == 27 && document.getElementById("searchInput").value != "" )
	{
		gOneClickExtension.ClearSearch();
		event.stopPropagation();
	}
}

//Add handlers
gOneClickExtension.Initialize = function() {
	
	//observe changes in add-on references...
    gOneClickExtension.prefObserver.register();

	gOneClickExtension.Preferences = gOneClickExtension.LoadPreferences();

    var app = Components.classes["@mozilla.org/xre/app-info;1"].
              getService(Components.interfaces.nsIXULAppInfo);

    gOneClickExtension.appVersion = app.version;

	window.addEventListener("keyup", gOneClickExtension.onWindowKeyUp, true);
	document.getElementById("threadTree").addEventListener("click",     gOneClickExtension.onClicked, true);
	document.getElementById("searchInput").addEventListener("keypress", gOneClickExtension.onSearchKeyPress, true);
    
    //is
    var em = Components.classes["@mozilla.org/extensions/manager;1"].getService(Components.interfaces.nsIExtensionManager);
    var ClearSubjectLocation = em.getInstallLocation("cleansubject@style-biz.de");
    gOneClickExtension.IsCleanSubjectInstalled = ClearSubjectLocation != null;
    
    if ( gOneClickExtension.IsCleanSubjectInstalled )
    {
        var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                     .getService(Components.interfaces.mozIJSSubScriptLoader);
        loader.loadSubScript("chrome://cleansubject/content/core.js");

        sbiz.CleanSubject.SetVariablesFromPreferences();
        sbiz.CleanSubject.SetPrefixArrayFromPreferences();

        dump('CleanSubject script is loaded...\n');
    }
};

// Clean up handlers
gOneClickExtension.Shutdown = function() {
    gOneClickExtension.prefObserver.unregister();

	window.removeEventListener("load", gOneClickExtension.Initialize, false);
	window.removeEventListener("unload", gOneClickExtension.Shutdown, false);

	window.removeEventListener("keyup", gOneClickExtension.onWindowKeyUp, true);

	document.getElementById("threadTree").removeEventListener("click",     gOneClickExtension.onClicked,     true);
	document.getElementById("searchInput").removeEventListener("keypress", gOneClickExtension.onSearchKeyPress, true);
};

window.addEventListener("load", gOneClickExtension.Initialize, false);
window.addEventListener("unload", gOneClickExtension.Shutdown, false);